package mylittleinvestigations.Screens;

import java.util.logging.Level;
import java.util.logging.Logger;
import mylittleinvestigations.Area;
import mylittleinvestigations.CaseInformation.Case;
import mylittleinvestigations.CaseInformation.CaseParseException;
import mylittleinvestigations.CaseInformation.CaseParsingEventListener;
import mylittleinvestigations.CaseInformation.CaseParsingEventProvider;
import mylittleinvestigations.GameUi.GameUiLoader;
import mylittleinvestigations.MouseHelper;
import mylittleinvestigations.PersistentThreads.RenderThread;
import mylittleinvestigations.Settings;
import mylittleinvestigations.Utils;
import org.dawnmew.jpurewave.SoundSystem;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;

public class GameScreen extends Screen implements CaseParsingEventListener
{
    public static final String Id = "GameScreen";
    private static int LoadingDotsUpdateDelayMs = 500;
    
    public static Area centralPonyvilleArea;
    public static Area cmcClubhouseArea;
    public static Area currentArea;
    
    private int numLoadingDots;
    private int timeSinceLastLoadingDotsUpdate;
    
    private boolean caseIsReady;
    private boolean caseNeedsReset;
    
    public GameScreen()
    {
        this.caseIsReady = false;
        this.numLoadingDots = 1;
        
        CaseParsingEventProvider.RegisterListener(this);
    }

    @Override
    public void Init()
    {
        this.isFinished = false;
        this.nextScreenId = null;
        this.caseNeedsReset = true;
            
        if (!this.caseIsReady)
        {
            Case.LoadFromXmlAsync("case1.case");
        }
    }

    public void Update(GameContainer gc, int delta)
    {
        if (!this.caseIsReady)
        {
            if (GameUiLoader.getInstance().getIsDialogFontLoaded())
            {
                this.timeSinceLastLoadingDotsUpdate += delta;

                while (this.timeSinceLastLoadingDotsUpdate > LoadingDotsUpdateDelayMs)
                {
                    this.timeSinceLastLoadingDotsUpdate -= LoadingDotsUpdateDelayMs;
                    this.numLoadingDots++;

                    if (this.numLoadingDots > 3)
                    {
                        this.numLoadingDots = 1;
                    }
                }
            }
            
            return;
        }
        
        if (this.caseNeedsReset)
        {
            Case.getInstance().Reset();
            this.ResetCase();
            this.caseNeedsReset = false;
        }
        
        if (Case.getInstance().getIsFinished())
        {
            SoundSystem.getInstance().stopMusic();
            this.isFinished = true;
            this.nextScreenId = TitleScreen.Id;
        }
        
        try
        {
            currentArea.Update(gc, delta);
        }
        catch (CaseParseException ex)
        {
            Logger.getLogger(GameScreen.class.getName()).log(Level.SEVERE, null, ex);
        }

        if (currentArea.getIsFinished())
        {
            if (currentArea == cmcClubhouseArea)
            {
                currentArea = centralPonyvilleArea;
            }
            else
            {
                currentArea = cmcClubhouseArea;
            }

            currentArea.Begin();
        }

        MouseHelper.ApplyCursorUpdate();
    }

    public void Draw(GameContainer gc, Graphics g)
    {
        if (!this.caseIsReady)
        {
            if (GameUiLoader.getInstance().getIsDialogFontLoaded())
            {
                String loadingString = "Loading";
                String loadStage = Case.getInstance().getLoadStage();
                
                if (!Utils.isNullOrWhiteSpace(loadStage))
                {
                    loadingString += " " + loadStage;
                }

                for (int i = 0; i < this.numLoadingDots; i++)
                {
                    loadingString += ".";
                }

                org.newdawn.slick.UnicodeFont dialogFont = GameUiLoader.getInstance().getDialogFont();
                RenderThread.getInstance().AddStringToRenderQueue(
                        dialogFont,
                        (float)(Settings.DisplayBounds.getX() / 2 - dialogFont.getWidth(loadingString) / 2),
                        (float)(Settings.DisplayBounds.getY() / 2 - dialogFont.getHeight(loadingString) / 2),
                        loadingString);
            }
            
            return;
        }
        else if (this.caseNeedsReset)
        {
            return;
        }
            
        try
        {
            currentArea.Draw(gc, g);
        }
        catch (CaseParseException ex)
        {
            Logger.getLogger(GameScreen.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (SlickException ex)
        {
            Logger.getLogger(GameScreen.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void OnCaseParsingComplete(String caseFileName)
    {
        if (Utils.equals(caseFileName, "case1.case"))
        {
            this.caseIsReady = true;
        }
    }
    
    private void ResetCase()
    {
        currentArea = Case.getInstance().getContent().GetAreaFromId(Case.getInstance().getContent().getInitialAreaId());
        centralPonyvilleArea = Case.getInstance().getContent().GetAreaFromId("CentralPonyville");
        cmcClubhouseArea = Case.getInstance().getContent().GetAreaFromId("CMCClubhouse");

        currentArea.Begin(Case.getInstance().getContent().getInitialLocationId());
    }
}
